package com.shop.admin.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shop.admin.constant.SeckillConstant;
import com.shop.admin.dao.ShopOrderDao;
import com.shop.admin.entity.*;
import com.shop.admin.service.*;
import com.shop.admin.utils.PageUtils;
import com.shop.admin.utils.Query;
import com.shop.admin.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

@Service
public class ShopOrderServiceImpl extends ServiceImpl<ShopOrderDao, ShopOrder> implements ShopOrderService  {
    @Autowired
    private ShopImageService imageService;
    @Autowired
    private ShopStockService stockService;
    @Autowired
    private ShopCategoryService categoryService;
    @Autowired
    private OrderTagService tagService;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<ShopOrder> queryWrapper = new QueryWrapper<>();
        String key= (String) params.get("key");
        if(!StringUtils.isEmpty(key)){
            queryWrapper.lambda().and((wrapper)->{
                wrapper.eq(ShopOrder::getOrderId,key).or().like(ShopOrder::getOrderName,key);
            });
        }

        String catalogId= (String) params.get("catalogId");
        if(!StringUtils.isEmpty(catalogId)&&!"0".equalsIgnoreCase(catalogId)){
            queryWrapper.lambda().eq(ShopOrder::getCatelogId,catalogId);
        }

        String status= (String) params.get("showStatus");
        if(!StringUtils.isEmpty(status)){
            queryWrapper.lambda().eq(ShopOrder::getShowStatus,status);
        }

        String orgId= (String) params.get("orgId");
        if(!StringUtils.isEmpty(orgId)){
            queryWrapper.lambda().eq(ShopOrder::getOrgId,orgId);
        }

        IPage<ShopOrder> page = this.page(
                new Query<ShopOrder>().getPage(params),
                queryWrapper.lambda().eq(ShopOrder::getTombstone,1)
        );
        List<ShopOrder> records = page.getRecords();
        Set<Integer> integerList = records.parallelStream().map(ShopOrder::getCatelogId).collect(Collectors.toSet());
        List<ShopCategory> categoryVOS = categoryService.list(new QueryWrapper<ShopCategory>().lambda()
                .select(ShopCategory::getCateId, ShopCategory::getCateName)
                .in(ShopCategory::getCateId, integerList)
        ).stream().collect(Collectors.toList());
        List<Long> orderId = records.stream().map(list -> {
            return list.getOrderId();
        }).collect(Collectors.toList());
        List<ShopStock> stockCount = stockService.selectCountList(orderId);
        Optional.ofNullable(stockCount).orElseThrow(() -> new RuntimeException("数据库查询为空"));
        List<ImagesIdVo> shopImages = imageService.selectImageList(orderId);
        Optional.ofNullable(shopImages).orElseThrow(() -> new RuntimeException("数据库查询为空"));
        List<OrderListVo> collect = records.parallelStream().map(item -> {
            OrderListVo orderVO = new OrderListVo();
            BeanUtils.copyProperties(item, orderVO);
                categoryVOS.forEach(cate -> {
                    if (cate.getCateId().equals(item.getCatelogId().longValue())) {
                        orderVO.setCateName(cate.getCateName());
                    }
                });
                stockCount.forEach(stock->{
                    if (stock.getOrderId().equals(item.getOrderId())){
                        orderVO.setStockCount(stock.getStockCount());
                    }
                });
                shopImages.forEach(image->{
                    if (image.getOrderId().equals(item.getOrderId())){
                        orderVO.setImagesList(image.getImagesList());
                    }
                });
            return orderVO;
        }).collect(Collectors.toList());
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(collect);
        return pageUtils;
    }


    @Override
    @Transactional
    public void removeMenuByIds(List<Long> asList) {
        for (Long aLong : asList) {
            //this.baseMapper.delete(new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getOrderId,aLong));
            ShopOrder shopOrder = new ShopOrder();
            shopOrder.setOrderId(aLong);
            shopOrder.setTombstone(0);
            this.baseMapper.updateById(shopOrder);
        }
//        CompletableFuture<Void> imageServiceCompletableFuture = CompletableFuture.runAsync(() -> {
//            imageService.removeImagesByOrderId(asList);
//        }, threadPoolExecutor);
//
//        CompletableFuture<Void> stockServiceCompletableFuture = CompletableFuture.runAsync(() -> {
//            stockService.removeStockByOrderId(asList);
//        }, threadPoolExecutor);
//
//        CompletableFuture.allOf(imageServiceCompletableFuture,stockServiceCompletableFuture);
    }

    @Override
    @Transactional
    public void saveOrderList(OrderVo vo) {
        ShopOrder orderDB=new ShopOrder();
        BeanUtils.copyProperties(vo,orderDB);
        orderDB.setCreateTime(new Date());
        orderDB.setUpdateTime(new Date());
        orderDB.setSaleCount(0l);
        orderDB.setTombstone(1);
        if(this.baseMapper.insert(orderDB)>0){
            List<Images> imageVOList = vo.getImagesList();
            CompletableFuture<Void> imageServiceCompletableFuture = CompletableFuture.runAsync(() -> {
                imageService.saveImages(orderDB.getOrderId(),imageVOList);
            }, threadPoolExecutor);
            ShopStock shopStock = new ShopStock();
            shopStock.setOrderId(orderDB.getOrderId());
            shopStock.setStockCount(vo.getStockCount());
            CompletableFuture<Void> stockServiceCompletableFuture = CompletableFuture.runAsync(() -> {
                stockService.insertStock(shopStock);
            }, threadPoolExecutor);
            CompletableFuture.allOf(imageServiceCompletableFuture,stockServiceCompletableFuture);
        }

    }

    @Override
    @Transactional
    public void updateDetail(OrderListVo vo) {
        ShopOrder shopOrder= new ShopOrder();
        BeanUtils.copyProperties(vo,shopOrder);

        CompletableFuture<Void> stockServiceCompletableFuture = CompletableFuture.runAsync(() -> {
            stockService.updateStockCount(vo.getOrderId(),vo.getStockCount());
        }, threadPoolExecutor);

        CompletableFuture<Void> imageServiceCompletableFuture = CompletableFuture.runAsync(() -> {
            imageService.updateImages(vo.getOrderId(),vo.getImagesList());
        }, threadPoolExecutor);

        CompletableFuture.allOf(stockServiceCompletableFuture,imageServiceCompletableFuture);
        shopOrder.setUpdateTime(new Date());
        this.update(shopOrder,new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getOrderId,shopOrder.getOrderId()));
    }


    @Override
    public ShopOrder selectById(Integer orderId) {
        ShopOrder shopOrder = this.baseMapper.selectOne(new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getOrderId, orderId));
        return shopOrder;
    }

    @Override
    public void removeOrdersByIds(List<Long> asList) {
//        for (Long aLong : asList) {
//            this.baseMapper.delete(new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getCatelogId,aLong));
//        }
        for (Long aLong : asList) {
            ShopOrder shopOrder = new ShopOrder();
            shopOrder.setTombstone(0);
            this.baseMapper.update(shopOrder,new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getCatelogId,aLong));
        }
    }

    @Override
    public boolean selectBoolean(String orderName,Integer orgId) {
        if (this.baseMapper.selectOne(new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getOrgId,orgId).eq(ShopOrder::getOrderName,orderName).eq(ShopOrder::getShowStatus,1))!=null){
            return false;
        }
        return true;
    }

    @Override
    public List<TagListVo> selectTagById(Long orderId) {
        List<TagListVo> vos = tagService.selectTagList(orderId);
        return vos;
    }

    @Override
    public void updateTagList(UpdateTagListVo listVO) {
        tagService.updateTagList(listVO);
    }

    @Override
    public void deleteTags(List<Long> asList) {
        tagService.deleteTags(asList);
    }

    @Override
    public void seckillStatus(SeckillStatusVo statusVO) {
        ShopOrder shopOrder=new ShopOrder();
        shopOrder.setSeckill(statusVO.getSeckill());
        shopOrder.setUpdateTime(new Date());
        this.update(shopOrder,new LambdaQueryWrapper<ShopOrder>().eq(ShopOrder::getOrderId,statusVO.getOrderId()));
    }

    @Override
    public PageUtils querySeckillPage(Map<String, Object> params) {
        LambdaQueryWrapper<ShopOrder> queryWrapper = new LambdaQueryWrapper<ShopOrder>()
                .eq(ShopOrder::getSeckill, SeckillConstant.StatusEnum.SECKILL.getCode())
                .eq(ShopOrder::getOrgId,params.get("orgId"));

        IPage<ShopOrder> page = this.page(
                new Query<ShopOrder>().getPage(params),
                queryWrapper
        );
        return new PageUtils(page);
    }

    @Override
    public void priceSeckill(SeckillPriceVo priceVO) {

        ShopOrder shopOrder=new ShopOrder();
        shopOrder.setPriceSeckill(priceVO.getPriceSeckill());
        shopOrder.setUpdateTime(new Date());
        this.update(shopOrder,new LambdaQueryWrapper<ShopOrder>().eq(ShopOrder::getOrderId,priceVO.getOrderId()));
    }


}
